import { 
  UserProfile, 
  AgendaItem, 
  Recommendation, 
  RecommendationReason,
  TechPreference,
  ExperienceLevel 
} from '@/types';
import { agendaItems } from '@/data/agenda';

// 推荐算法权重配置
const WEIGHTS = {
  TECH_MATCH: 0.4,      // 技术匹配权重
  LEVEL_MATCH: 0.3,     // 难度匹配权重
  TIME_PREFERENCE: 0.2, // 时间偏好权重
  POPULARITY: 0.1       // 热度权重
};

// 计算技术标签匹配度
const calculateTechMatch = (
  userPreferences: TechPreference[], 
  itemTags: TechPreference[]
): number => {
  if (userPreferences.length === 0 || itemTags.length === 0) return 0;
  
  const matches = itemTags.filter(tag => userPreferences.includes(tag)).length;
  return matches / Math.max(userPreferences.length, itemTags.length);
};

// 计算难度匹配度
const calculateLevelMatch = (
  userLevel: ExperienceLevel, 
  itemLevel: ExperienceLevel
): number => {
  const levelScores = {
    'beginner': 1,
    'intermediate': 2, 
    'advanced': 3,
    'expert': 4
  };
  
  const userScore = levelScores[userLevel];
  const itemScore = levelScores[itemLevel];
  const diff = Math.abs(userScore - itemScore);
  
  // 完全匹配得1分，差1级得0.7分，差2级得0.4分，差3级得0.1分
  if (diff === 0) return 1.0;
  if (diff === 1) return 0.7;
  if (diff === 2) return 0.4;
  return 0.1;
};

// 计算时间偏好匹配度
const calculateTimeMatch = (
  userTimePreferences: string[], 
  itemStartTime: Date
): number => {
  const hour = itemStartTime.getHours();
  const timeSlot = hour < 12 ? 'morning' : 'afternoon'; // 大会只有上午和下午场次
  
  if (userTimePreferences.includes('full_day') || userTimePreferences.includes(timeSlot)) {
    return 1.0;
  }
  
  return 0.3; // 不匹配但不完全排除
};

// 计算热度评分
const calculatePopularityScore = (item: AgendaItem): number => {
  const attendanceRate = (item.currentAttendees || 0) / (item.maxAttendees || 1);
  const ratingScore = (item.rating || 0) / 5;
  const keynoteBonus = item.isKeynote ? 0.2 : 0;
  
  return Math.min(1.0, attendanceRate * 0.5 + ratingScore * 0.5 + keynoteBonus);
};

// 生成推荐理由
const generateReasons = (
  item: AgendaItem,
  profile: UserProfile,
  scores: {
    techMatch: number;
    levelMatch: number;
    timeMatch: number;
    popularity: number;
  }
): RecommendationReason[] => {
  const reasons: RecommendationReason[] = [];

  // 技术匹配理由
  if (scores.techMatch > 0.6) {
    const matchedTags = item.tags.filter(tag => 
      profile.techPreferences.includes(tag)
    );
    reasons.push({
      type: 'tech_match',
      description: `与您关注的技术领域高度匹配：${matchedTags.join('、')}`,
      weight: scores.techMatch
    });
  }

  // 难度匹配理由
  if (scores.levelMatch > 0.7) {
    reasons.push({
      type: 'level_match',
      description: `难度级别与您的经验水平匹配`,
      weight: scores.levelMatch
    });
  }

  // 时间偏好理由
  if (scores.timeMatch > 0.8) {
    reasons.push({
      type: 'time_preference',
      description: `符合您偏好的时间段`,
      weight: scores.timeMatch
    });
  }

  // 热度理由
  if (scores.popularity > 0.7) {
    reasons.push({
      type: 'popularity',
      description: `热门会议，评分${item.rating}分，已有${item.currentAttendees}人参加`,
      weight: scores.popularity
    });
  }

  // 主题演讲特殊标记
  if (item.isKeynote) {
    reasons.push({
      type: 'speaker_quality',
      description: '重要主题演讲，不容错过',
      weight: 1.0
    });
  }

  return reasons;
};

// 主推荐算法
export const generateRecommendations = (
  profile: UserProfile,
  limit: number = 10
): Recommendation[] => {
  const recommendations: Recommendation[] = [];

  for (const item of agendaItems) {
    // 计算各维度评分
    const techMatch = calculateTechMatch(profile.techPreferences, item.tags);
    const levelMatch = calculateLevelMatch(profile.experienceLevel, item.level);
    const timeMatch = calculateTimeMatch(profile.timePreferences, item.startTime);
    const popularity = calculatePopularityScore(item);

    // 计算综合评分
    const totalScore = 
      techMatch * WEIGHTS.TECH_MATCH +
      levelMatch * WEIGHTS.LEVEL_MATCH +
      timeMatch * WEIGHTS.TIME_PREFERENCE +
      popularity * WEIGHTS.POPULARITY;

    // 生成推荐理由
    const reasons = generateReasons(item, profile, {
      techMatch,
      levelMatch,
      timeMatch,
      popularity
    });

    // 计算置信度
    const confidence = Math.min(1.0, 
      (techMatch + levelMatch + timeMatch + popularity) / 4
    );

    recommendations.push({
      agendaItem: item,
      score: totalScore,
      reasons,
      confidence
    });
  }

  // 按评分排序并返回前N个
  return recommendations
    .sort((a, b) => b.score - a.score)
    .slice(0, limit);
};

// 基于特定条件的推荐
export const getRecommendationsByCategory = (
  profile: UserProfile,
  category: string,
  limit: number = 5
): Recommendation[] => {
  const filteredItems = agendaItems.filter(item => 
    category === 'all' || item.category === category
  );

  const recommendations: Recommendation[] = [];

  for (const item of filteredItems) {
    const techMatch = calculateTechMatch(profile.techPreferences, item.tags);
    const levelMatch = calculateLevelMatch(profile.experienceLevel, item.level);
    const timeMatch = calculateTimeMatch(profile.timePreferences, item.startTime);
    const popularity = calculatePopularityScore(item);

    const totalScore = 
      techMatch * WEIGHTS.TECH_MATCH +
      levelMatch * WEIGHTS.LEVEL_MATCH +
      timeMatch * WEIGHTS.TIME_PREFERENCE +
      popularity * WEIGHTS.POPULARITY;

    const reasons = generateReasons(item, profile, {
      techMatch,
      levelMatch,
      timeMatch,
      popularity
    });

    const confidence = Math.min(1.0, 
      (techMatch + levelMatch + timeMatch + popularity) / 4
    );

    recommendations.push({
      agendaItem: item,
      score: totalScore,
      reasons,
      confidence
    });
  }

  return recommendations
    .sort((a, b) => b.score - a.score)
    .slice(0, limit);
};

// 获取多样性推荐（确保推荐结果涵盖不同技术领域）
export const getDiverseRecommendations = (
  profile: UserProfile,
  limit: number = 10
): Recommendation[] => {
  const allRecommendations = generateRecommendations(profile, agendaItems.length);
  const diverseRecommendations: Recommendation[] = [];
  const usedTags = new Set<string>();

  // 首先选择评分最高的
  if (allRecommendations.length > 0) {
    diverseRecommendations.push(allRecommendations[0]);
    allRecommendations[0].agendaItem.tags.forEach(tag => usedTags.add(tag));
  }

  // 然后选择不同技术领域的推荐
  for (const rec of allRecommendations.slice(1)) {
    if (diverseRecommendations.length >= limit) break;

    const hasNewTag = rec.agendaItem.tags.some(tag => !usedTags.has(tag));
    
    if (hasNewTag || diverseRecommendations.length < limit / 2) {
      diverseRecommendations.push(rec);
      rec.agendaItem.tags.forEach(tag => usedTags.add(tag));
    }
  }

  // 如果还没达到限制数量，继续添加高评分的
  while (diverseRecommendations.length < limit && diverseRecommendations.length < allRecommendations.length) {
    const remaining = allRecommendations.filter(rec => 
      !diverseRecommendations.includes(rec)
    );
    
    if (remaining.length === 0) break;
    diverseRecommendations.push(remaining[0]);
  }

  return diverseRecommendations;
};